package cn.xjfcloud.onedriveserver.controller;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.fasterxml.jackson.databind.ObjectMapper;

import cn.xjfcloud.onedriveserver.pojo.FileInfo;
import cn.xjfcloud.onedriveserver.pojo.dto.ApiConfig;
import cn.xjfcloud.onedriveserver.pojo.dto.CommonConfig;
import cn.xjfcloud.onedriveserver.pojo.dto.DownloadLog;
import cn.xjfcloud.onedriveserver.pojo.dto.OnedriveFileInfo;
import cn.xjfcloud.onedriveserver.service.ApiConfigService;
import cn.xjfcloud.onedriveserver.service.DownloadLogService;
import cn.xjfcloud.onedriveserver.service.UploadFileService;
import cn.xjfcloud.onedriveserver.util.ApiUtil;
import cn.xjfcloud.onedriveserver.util.FileSystemUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;

@Api
@RestController
public class GetFileController {
	private static final Logger Log = LoggerFactory.getLogger(GetFileController.class);
	private static final ObjectMapper objectMapper = new ObjectMapper();
	private static final CommonConfig COMMON_CONFIG = new CommonConfig();
	@Autowired
	private UploadFileService uploadFileService;
	@Autowired
	private DownloadLogService downloadLogService;
	@Autowired
	private ApiConfigService apiConfigService;

	/**
	 * 下载文件
	 * 
	 * @param fileId
	 * @param response
	 * @param request
	 */
	@ApiOperation(value = " 下载文件", notes = " 下载文件")
	@RequestMapping("/file/{fileId}")
	public void downloadFile(@ApiParam(value = "文件id") @PathVariable("fileId") String fileId,
			HttpServletResponse response, HttpServletRequest request) {
		InputStream inputStream;
		OnedriveFileInfo onedriveFileInfo = uploadFileService.getOnedriveFileInfoByFileId(fileId);
		Integer apiConfigId = onedriveFileInfo.getApiConfigId();
		try {
			response.setContentType("application/json");
			
			if (apiConfigService.makeTokenUseful(apiConfigId)  == 0) {
				PrintWriter writer = response.getWriter();
				writer.write("{\"code\":\"10001\",\"msg\":\"token not avilable\"}");
				return;
			}
			if(onedriveFileInfo.getFileSize() == null) {
				PrintWriter writer = response.getWriter();
				writer.write("{\"code\":\"10002\",\"msg\":\"file not upload complete\"}");
				return;
			}
			response.setContentType("application/octet-stream");
			response.setHeader("Content-Disposition",
					"attachment;fileName=" + URLEncoder.encode(onedriveFileInfo.getFileName()));
			ApiConfig apiConfig = apiConfigService.getApiConfigById(apiConfigId);
			// 根据请求头获取inputStream
			Map<String, Object> resultMap = ApiUtil.getDownloadInputStream(onedriveFileInfo.getOnedrivePath(),
					request.getHeader("Range"), apiConfig);

			DownloadLog downloadLog = new DownloadLog();
			downloadLog.setOnedriveFileId(onedriveFileInfo.getId());
			downloadLog.setRequestIp(request.getRemoteHost());
			downloadLog.setRecordTime(new Date());
			Long contentLength = (Long) resultMap.get("contentLength");
			downloadLog.setSize(contentLength);
			// 开始下载
			String contentRange = (String) resultMap.get("contentRange");
			if (!StringUtils.isEmpty(contentRange)) {
				downloadLog.setIsPartDownload(1);
				response.setHeader("Content-Range", contentRange);
				response.setStatus(206);
			}
			// 存入下载历史
			downloadLogService.addDownloadLog(downloadLog);
			response.setContentLengthLong(contentLength);
			inputStream = (InputStream) resultMap.get("inputStream");
			// 读取inputStreams
			int len = 0;
			byte[] b = new byte[1024];
			OutputStream outputStream = response.getOutputStream();
			while ((len = inputStream.read(b)) != -1) {
				outputStream.write(b, 0, len);
			}
			inputStream.close();
		} catch (IOException e) {
			e.printStackTrace();
			Log.error("--------------------->错误", e);
		}
	}
	
	/**
	 * 获取文件夹下所有文件
	 * 
	 * @param path
	 * @return
	 */
	@ApiOperation(value = "获取文件夹下所有文件", notes = "获取文件夹下所有文件")
	@GetMapping("getDirectoryAllFile")
	public Map<String, Object> getDirectoryAllFile(@ApiParam(required = false, name = "path", value = "服务器文件夹地址") String path) {
		Map<String, Object> resultMap = new HashMap<String, Object>();
		List<FileInfo> fileInfoList = new ArrayList<FileInfo>();
		if (StringUtils.isEmpty(path)) {
			// 没有传入path，就判断默认path有没有
			if (StringUtils.isEmpty(COMMON_CONFIG.getRootFilePath())) {
				// 默认path也没有值，返回错误信息
				resultMap.put("code", "10001");
				resultMap.put("msg", "not set root filepath");
				return resultMap;
			} else {
				
				FileInfo fileInfo = FileSystemUtil.getDirctoryAllFile(COMMON_CONFIG.getRootFilePath());
				fileInfoList.add(fileInfo);
				resultMap.put("code", "0");
				resultMap.put("fileInfoList", fileInfoList);
				return resultMap;
			}
		} else {
			// 传入有path
			FileInfo fileInfo = FileSystemUtil.getDirctoryAllFile(path);
			fileInfoList.add(fileInfo);
			resultMap.put("code", "0");
			resultMap.put("fileInfoList", fileInfoList);
			return resultMap;
		}
	}
	

}
